//
// Created by martin on 2/25/22.
//

#include "muduo/base/ThreadPool.h"
#include "muduo/base/CountDownLatch.h"
#include "muduo/base/CurrentThread.h"
#include "muduo/base/Logging.h"

#include <stdio.h>
#include <unistd.h>

void print()
{
    printf("tid=%d\n", muduo::CurrentThread::tid());
}

void printString(const std::string& str)
{
    LOG_INFO << str;
    usleep(100*1000);
}

void test(int maxSize)
{
    LOG_WARN << "Test ThreadPool with max queue fileSize = " << maxSize;
    muduo::ThreadPool pool("MainThreadPool");
    pool.setMaxQueueSize(maxSize);
    pool.start(5);

    LOG_WARN << "Adding";
    pool.run(print);
    pool.run(print);
    for (int i = 0; i < 100; ++i) {
        char buf[32];
        snprintf(buf, sizeof(buf), "task %d", i);
        pool.run(std::bind(printString, std::string(buf)));
    }
    LOG_WARN << "Done";

    muduo::CountDownLatch latch(1);
    pool.run(std::bind(&muduo::CountDownLatch::countDown, &latch));
    latch.wait(); // wait for pool running latch.countDown()
    pool.stop();
}

void longTask(int num)
{
    LOG_INFO << "longTask" << num;
    muduo::CurrentThread::sleepUsec(3000000);
}

void test2()
{
    LOG_WARN << "Test ThreadPool by stopping early.";
    muduo::ThreadPool pool("ThreadPool");
    pool.setMaxQueueSize(5);
    pool.start(3);

    // thread1线程交给pool运行20次longTask(i)
    muduo::Thread thread1([&pool](){
        for (int i = 0; i < 20; ++i) {
            pool.run(std::bind(longTask, i));
        }
    },
                          "thread1");
    thread1.start();

    muduo::CurrentThread::sleepUsec(5000000);
    LOG_WARN << "stop pool";
    pool.stop(); // early stop

    thread1.join(); // 连接thread1
    // run() after stop()
    pool.run(print); // pool has been not running
    LOG_WARN << "test2 Done";
}

int main()
{
    test(0);
    test(1);
    test(5);
    test(10);
    test(50);
    test2();
    return 0;
}
